/*
 Copyright (C) 2013 Yuyao Liang

 This source code is release under the BSD License.

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.
 

 */
package com.googlecode.stereoplot;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.geom.Arc2D;
import java.awt.geom.Area;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;

import org.jfree.chart.axis.ColorBar;
import org.jfree.chart.plot.dial.DialLayerChangeEvent;
import org.jfree.chart.plot.dial.DialPlot;

/**
 * @author lianyuy
 * 
 */
@SuppressWarnings("deprecation")
public class StereoPlotLayer extends StereoGridLayer {
	private int datasetIndex;
	private ColorBar colorBar = null;

	public StereoPlotLayer() {
		datasetIndex = 0;
	}

	public StereoPlotLayer(ColorBar colorBar) {
		this();
		this.colorBar = colorBar;
	}

	/**
	 * Returns the scale index.
	 * 
	 * @return The scale index.
	 * 
	 * @see #setDatasetIndex(int)
	 */
	public int getDatasetIndex() {
		return this.datasetIndex;
	}

	/**
	 * Sets the scale index and sends a {@link DialLayerChangeEvent} to all
	 * registered listeners.
	 * 
	 * @param index
	 *            the scale index.
	 * 
	 * @see #getDatasetIndex()
	 */
	public void setDatasetIndex(int index) {
		this.datasetIndex = index;
		notifyListeners(new DialLayerChangeEvent(this));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.jfree.chart.plot.dial.DialLayer#draw(java.awt.Graphics2D,
	 * org.jfree.chart.plot.dial.DialPlot, java.awt.geom.Rectangle2D,
	 * java.awt.geom.Rectangle2D)
	 */
	@Override
	public void draw(Graphics2D g2, DialPlot plot, Rectangle2D frame,
			Rectangle2D view) {
		Rectangle2D nintyDegreeRectInner = DialPlot.rectangleByRadius(frame,
				StereoGridLayer.NintyDegreeRadius,
				StereoGridLayer.NintyDegreeRadius);
		Arc2D arcNintyyDegree = new Arc2D.Double(nintyDegreeRectInner, 0, 360,
				Arc2D.OPEN);

		g2.setPaint(this.paint);
		g2.setStroke(new BasicStroke(2.0f));

		if (plot instanceof StereoDialPlot) {
			StereoPlotDataQuickSeries series = ((StereoDialPlot) plot)
					.getStereoPlotDataQuickSeries();
			Area area = new Area(arcNintyyDegree);
			double centerX = area.getBounds2D().getCenterX();
			double centerY = area.getBounds2D().getCenterY();
			double width = area.getBounds2D().getWidth();
			double height = area.getBounds2D().getHeight();
			BufferedImage canvas = new BufferedImage((int) width + 1,
					(int) height + 1, BufferedImage.TYPE_INT_ARGB);

			int offsetx = (int) (centerX - width / 2);
			int offsety = (int) (centerY - height / 2);

			for (int i = 0; i <= width; i++) {
				for (int j = 0; j <= height; j++) {
					double x = i - width / 2;
					double y = j - height / 2;
					double beta = height / width;
					double theta = Math.atan2(y, beta * x);
					double a = x / Math.cos(theta);

					double deviate = a / width * Math.PI;
					if (deviate > Math.PI / 2)
						continue;
					double azimuth = Math.PI / 2 - theta;

					double value = getStereoPlotValue(azimuth, deviate, series);
					int color = getColorByValue(value);
					canvas.setRGB(i, j, color);
				}
			}
			g2.drawImage(canvas, null, offsetx, offsety);
		}

	}

	/**
	 * @param value
	 * @return
	 */
	private int getColorByValue(double value) {
		Paint paint = colorBar.getPaint(value);
		return ((Color) paint).getRGB();
	}

	/**
	 * @param azimuth
	 * @param deviate
	 * @return
	 */
	private double getStereoPlotValue(double azimuth, double deviate,
			StereoPlotDataQuickSeries series) {
		return series.getBestValue(azimuth, deviate);
	}

}
